package com.sikaryofficial.backend.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sikaryofficial.backend.domain.entity.UserCertificate;
import com.sikaryofficial.backend.mapper.UserCertificateMapper;
import com.sikaryofficial.backend.service.IUserCertificateService;
import com.sikaryofficial.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 用户证明Service业务层处理
 *
 * @author qinjinyuan
 * @date 2023-11-18
 */
@Service
public class UserCertificateServiceImpl extends ServiceImpl<UserCertificateMapper, UserCertificate> implements IUserCertificateService {
    @Autowired
    private UserCertificateMapper userCertificateMapper;

    /**
     * 上传18岁证明
     *
     * @param certificateUrl 证明地址
     * @param userId         用户id
     * @return 是否上传成功
     */
    @Override
    public boolean update18thProof(String certificateUrl, Long userId) {
        UserCertificate userCertificate = this.getOne(new LambdaQueryWrapper<UserCertificate>()
                .eq(UserCertificate::getCreatedBy, userId)
                .eq(UserCertificate::getCertificateType, 1)
                .eq(UserCertificate::getDeletedVersion, 0L)
                .last(" limit 1")
        );
        if (Objects.isNull(userCertificate)) {
            userCertificate = UserCertificate.builder()
                    .certificateType(1)
                    .createdBy(SecurityUtils.getUserId())
                    .createdTime(new Date())
                    .certificateUrl(certificateUrl)
                    .build();
            return this.save(userCertificate);
        } else {
            return this.update(new LambdaUpdateWrapper<UserCertificate>()
                    .set(UserCertificate::getCertificateUrl, certificateUrl)
                    .set(UserCertificate::getUpdatedTime, new Date())
                    .set(UserCertificate::getUpdatedBy, userId)
                    .eq(UserCertificate::getUserCertificateId, userCertificate.getUserCertificateId())
            );
        }
    }

    /**
     * 验证18岁证明
     *
     * @param userId 用户id
     * @return 是否验证成功
     */
    @Override
    public boolean validate18thProof(Long userId) {
        int result = this.count(new LambdaQueryWrapper<UserCertificate>()
                .eq(UserCertificate::getCreatedBy, userId)
                .eq(UserCertificate::getCertificateType, 1)
                .eq(UserCertificate::getDeletedVersion, 0L)
        );
        return result > 0;
    }

    /**
     * 获取18岁证明
     *
     * @param userId 用户id
     * @return 证明地址
     */
    @Override
    public String get18thProof(Long userId) {
        UserCertificate certificate = this.getOne(new LambdaQueryWrapper<UserCertificate>()
                .eq(UserCertificate::getCreatedBy, userId)
                .eq(UserCertificate::getCertificateType, 1)
                .eq(UserCertificate::getDeletedVersion, 0L)
                .last(" limit 1")
        );

        // 使用 Optional.ofNullable 判定 certificate 对象是否为空，并且返回CertificateUrl
        AtomicReference<String> url = new AtomicReference<>("");
        Optional.ofNullable(certificate).ifPresent(certificate1 -> url.set(certificate1.getCertificateUrl()));
        return url.get();
    }

    /**
     * 根据多个用户id获取18岁证明
     *
     * @param userIds
     * @return
     */
    @Override
    public Map<Long, String> get18thProofMap(Set<Long> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return null;
        }
        List<UserCertificate> certificates = this.list(new LambdaQueryWrapper<UserCertificate>()
                .in(UserCertificate::getCreatedBy, userIds)
                .eq(UserCertificate::getCertificateType, 1)
                .eq(UserCertificate::getDeletedVersion, 0L)
        );
        return certificates.stream().filter(item-> Objects.nonNull(item.getCertificateUrl()))
                .collect(Collectors.toMap(UserCertificate::getCreatedBy, UserCertificate::getCertificateUrl, (k1, k2) -> k1));
    }
}
